﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace RoMFramework
{
    public static class Utilities
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern bool VirtualProtectEx(IntPtr hProcess, IntPtr lpAddress,
           UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);

        public enum MemoryProtect
        {
            PAGE_EXECUTE = 0x10,
            PAGE_EXECUTE_READ = 0x20,
            PAGE_EXECUTE_READWRITE = 0x40,
            PAGE_EXECUTE_WRITECOPY = 0x80,
            PAGE_NOACCESS = 0x01,
            PAGE_READONLY = 0x02,
            PAGE_READWRITE = 0x04,
            PAGE_WRITECOPY =0x08

        }

        /// <summary>
        /// Changes the protection on a region of committed pages in the virtual address space of a specified process.
        /// </summary>
        /// <param name="hProcess">A handle to the process whose memory protection is to be changed.</param>
        /// <param name="lpAddress">The base address of the region of pages whose access protection attributes are to be changed.</param>
        /// <param name="dwSize">The size of the region whose access protection attributes are changed, in bytes.</param>
        /// <param name="NewProtection">The memory protection option. This parameter can be one of the <see cref="MemoryProtect"/> enums.</param>
        /// <param name="OldProtection">The old memory protection option. This parameter will be one of the <see cref="MemoryProtect"/> enums</param>
        static public void VirtualProtect(IntPtr hProcess, IntPtr lpAddress, UIntPtr dwSize, MemoryProtect NewProtection, out MemoryProtect OldProtection)
        {
            uint tmpVar;
            if (!VirtualProtectEx(hProcess, lpAddress, dwSize, (uint)NewProtection, out tmpVar))
            {
                Console.Instance.AddLine("Setting memory page protection failed");
                int errorcode = Marshal.GetLastWin32Error();
                throw new Win32Exception();
            }
            OldProtection = (MemoryProtect)tmpVar;
        }

        public static string BytetoString(byte[] buffer)
        {
            try
            {
                string result = "";
                for (int i = (buffer.Length); i != 0; i--)
                {
                    result += BitConverter.ToString(buffer, i - 1, 1);
                }
                return result;
            }
            catch
            {
                return "0";
            }
        }

        public static byte[] GetSubByteArray(byte[] array, int index, int count)
        {
            if (index >= array.Length || count > array.Length - index)
            {
                return array;
            }
            byte[] tempbytes = new byte[count];
            for (int i = 0; i < count; i++)
            {
                tempbytes[i] = array[index + i];
            }
            return tempbytes;
        }


        public static double RadianToDegrees(double angle)
        {
            return angle * (180.0 / Math.PI);
        }

        public static double DegreesToRadian(double angle)
        {
            return Math.PI * angle / 180.0;
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        public static extern bool FreeLibrary(IntPtr hModule);

        [DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
        public static extern UIntPtr GetProcAddress(IntPtr hModule, string procName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetModuleHandle(string lpModuleName);
    }
}
